package cn.shoptnt.service.trade.order.command.impl;

import cn.shoptnt.client.goods.GoodsClient;
import cn.shoptnt.framework.exception.ServiceException;
import cn.shoptnt.framework.rabbitmq.MessageSender;
import cn.shoptnt.framework.rabbitmq.MqMessage;
import cn.shoptnt.framework.util.LogUtils;
import cn.shoptnt.framework.util.StringUtil;
import cn.shoptnt.mapper.trade.order.OrderItemsMapper;
import cn.shoptnt.mapper.trade.order.OrderMapper;
import cn.shoptnt.model.base.message.OrderStatusChangeMsg;
import cn.shoptnt.model.base.rabbitmq.AmqpExchange;
import cn.shoptnt.model.errorcode.TradeErrorCode;
import cn.shoptnt.model.goods.vo.GoodsSkuVO;
import cn.shoptnt.model.promotion.tool.enums.PromotionTypeEnum;
import cn.shoptnt.model.trade.cart.vo.CartPromotionVo;
import cn.shoptnt.model.trade.order.dos.OrderDO;
import cn.shoptnt.model.trade.order.dos.OrderItemsDO;
import cn.shoptnt.model.trade.order.dto.OrderDTO;
import cn.shoptnt.model.trade.order.enums.OrderStatusEnum;
import cn.shoptnt.model.trade.order.enums.PayStatusEnum;
import cn.shoptnt.model.trade.order.enums.PaymentTypeEnum;
import cn.shoptnt.model.trade.order.vo.CommandResult;
import cn.shoptnt.model.trade.order.vo.OrderSkuVO;
import cn.shoptnt.service.trade.order.command.OrderCreateCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 订单信息入库命令执行器
 *
 * @author dmy
 * @version 1.0
 * 2022-01-15
 */
@Service
public class OrderIntoDBCommand implements OrderCreateCommand {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemsMapper orderItemsMapper;
    @Autowired
    private GoodsClient goodsClient;
    @Autowired
    private MessageSender messageSender;


    @Override
    public CommandResult execute(OrderDTO orderDTO) {
        //构建默认执行结果
        CommandResult result = new CommandResult(true, "成功");

        result.setRollback(this, orderDTO);

        try {
            //订单入库
            this.orderIntoDB(orderDTO);
        } catch (Exception e) {
            e.printStackTrace();
            result.setResult(false);
            result.setErrorMessage("订单信息入库失败");
        }

        return result;
    }


    /**
     * 订单信息入库
     *
     * @param order 订单信息
     */
    private void orderIntoDB(OrderDTO order) {
        //将DTO转换DO
        OrderDO orderDO = new OrderDO(order);

        //根据订单编号获取订单扣减库存结果
        Double orderPrice = order.getOrderPrice();
        //如果当前订单扣减库存失败，则修改订单状态为出库失败

        if (orderPrice == 0 && !order.getPaymentType().equals(PaymentTypeEnum.COD.value())) {
            //如果锁库存成功，并且待支付金额为0，则状态变成已付款
            orderDO.setOrderStatus(OrderStatusEnum.PAID_OFF.value());
            orderDO.setPayStatus(PayStatusEnum.PAY_YES.value());
        } else {
            //否则订单是已确认状态（锁库成功）
            orderDO.setOrderStatus(OrderStatusEnum.CONFIRM.value());
        }
        if (StringUtil.isEmpty(orderDO.getSn())) {
            throw new ServiceException(TradeErrorCode.E452.name(), "订单编号为空无法创建订单");
        }

        //订单信息入库
        orderMapper.insert(orderDO);

        //订单项入库
        for (OrderSkuVO skuVO : order.getOrderSkuList()) {
            orderItemsIntoDB(orderDO, skuVO);
        }

        //订单mq消息
        OrderStatusChangeMsg orderStatusChangeMsg = new OrderStatusChangeMsg();
        orderStatusChangeMsg.setOrderDO(orderDO);
        orderStatusChangeMsg.setOldStatus(OrderStatusEnum.valueOf(orderDO.getOrderStatus()));
        orderStatusChangeMsg.setNewStatus(OrderStatusEnum.valueOf(orderDO.getOrderStatus()));
        orderStatusChangeMsg.setOrderDTO(order);
        LogUtils.sendInfo("创建订单" + orderDO.getSn());
        this.messageSender.send(new MqMessage(AmqpExchange.ORDER_STATUS_CHANGE, AmqpExchange.ORDER_STATUS_CHANGE + "_ROUTING", orderStatusChangeMsg));
    }

    /**
     * 保存订单项信息
     *
     * @param orderDO
     * @param skuVO
     */
    private void orderItemsIntoDB(OrderDO orderDO, OrderSkuVO skuVO) {
        GoodsSkuVO goodsSkuVO = this.goodsClient.getSkuFromCache(skuVO.getSkuId());

        OrderItemsDO item = new OrderItemsDO(goodsSkuVO);
        item.setOrderSn(orderDO.getSn());
        item.setTradeSn(orderDO.getTradeSn());
        item.setNum(skuVO.getNum());
        item.setPrice(skuVO.getPurchasePrice());

        //判断是否为团购优惠
        List<CartPromotionVo> singleList = skuVO.getSingleList();
        if (singleList != null && !singleList.isEmpty()) {
            for (CartPromotionVo cartPromotionVo : singleList) {
                if (PromotionTypeEnum.GROUPBUY.toString().equals(cartPromotionVo.getPromotionType())) {
                    item.setPromotionType(cartPromotionVo.getPromotionType());
                    item.setPromotionId(cartPromotionVo.getPromotionId());
                    break;
                }
            }
        }
        orderItemsMapper.insert(item);
    }


    @Override
    public void rollback(OrderDTO order) {

    }

}
